perm filename F8OLD[3,ALS] blob sn#289769 filedate 1977-06-26 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00015 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002				    Checkers on an F8
C00007 00003	Approximate ROM space requirements (ball park guesses at best)
C00008 00004	RAM Data space requirements in bytes for a look-aread of 10
C00015 00005	TENTATIVE DATA STORAGE MAP
C00019 00006	*CTAB EMPTY and LEGAL codes
C00029 00007	Subroutine to  move 4 bytes from RAM to Scratchpad registers	16 thru 19
C00031 00008	* Registers, Subroutines
C00038 00009	* FORE AFT FIND
C00043 00010	*SELECT is entered with H set for the correct ply position in RAM
C00049 00011	UPDATE
C00050 00012	Evaluation
C00051 00013	α-β Scoring
C00052 00014	Opponents move checking
C00053 00015	DISPLAY
C00054 ENDMK
C⊗;
			    Checkers on an F8

The following is a first cut at trying to formulate the problem of writing
a simplified checker playing program to run on the F8.  The general idea
is to limit the storage space requirements at the expense of running time.
One would hope to produce a program that could challenge an amateur but
that would not necessarily interest a checker master.  It should also be
possible for the user to select several levels of play.

General procedure

Play consists of investigating the consequences of all legal moves by
carrying out a tree search of all posible replies and counter replies to a
depth (defined as the ply) of perhaps 4. Because of jump moves it will be
necessary to go to much further along the tree on occasion and a maximum
depth of perhaps 10 seems to be indicated.  The quality of play could be
fixed at one of several levels under operator control by changes to the
permited ply levels.  Only a rudimentary evaluation would be done at the
ends of the tree but once the rest of the program was written then any
remaining code space could be used to elaborate on this function.

The procedure will be roughly as follows:

A	Set up initial board position
B	Display board position
	Ask opponent to chose side
	If opponent choses White, randomly select a stored first move 
	    (One might also have some stored first replies)
D	Display board and wait for opponents move
	Check opponents move for legallity
	Display board if move is legal and go to 1
	Report non-acceptance and go to D

General tree search to a minimum depth of 4 and a maximum depth of 10
2:	Select next legal move
	If no moves available go to 5
3:	Make move and find the resulting board
	Add 1 to ply counter
1:	Find all legal moves
	If ply <4 go to 2
	Evaluate current board position in terms of 5 parameters
	If opponent's move go to 2
	If jump move go to 2
4:	Select only move that leads to a non-jump reply
	If move available go to 3
	If no moves lead to a non-jump reply then if ply≤10 go to 2
	Evaluate terminal position
5:	Make α-β comparison of score with previous level and back score
	If ply=0 go to 6
	Back up a level and subtract 1 from ply counter
	If ply <4 go to 2
	If jump move go to 2
	If opponents move go to 2
	Go to 4

6:	If score is a win or lose,announce results and go to A
	Report best machine move and  go to D
Approximate ROM space requirements (ball park guesses at best)

Routine		Normal		Minimum

Legal		200		100
Select		 50		 20
Update		200		100
Evaluate	200		100
α-β score	 50		 50
Back up		 50		 30
Check move	 50		 30
Display		400		200
Report win-lose  50		 20

Totals	       1250		650
RAM Data space requirements in bytes for a look-aread of 10
	Note: Most of this space can be freed to report the final move,
	      to updating the display and to check the opponents move.

Function	Normal 		Minimum

Board		10@12  120	10@12  120
Moves		10@16  160	10@1    10
Flags		10@2    20	10@2    20
Score		10@2    20	10@1    10

Totals		       320	       160

It would be desirable to keep some of these data in the scratchpad
registers.  It seems reasonable to try to keep one board position, enough
bytes to specify one or more possible moves and one resulting board
position.  During look-ahead (that is while moving forward along the
tree), one would transfer the old initial board position and any unused
move information to RAM storage, move the just found board to the
initial-board position and generate and store new move information, to
again repeat the process.  This would require at least 16 of the
scratchpad registers.

Actually at evaluation time it would be nice to be able to keep two
complete levels (with all move information retained) in scratchpad memory.
This would completely fill the scratchpad memory and leave no space for
intermediate results, so some compromise will have to be worked out.
Scratchpad space will always be in short supply.

General philosophy of storing boards and moves

Since there are numerous Bytes required to specify the data needed to
determine legal moves, to select one of these for investigation and to
produce the next board along the tree, it seems reasonable to group these
data togather and to go from one level in the tree to the next by
incrementing a saved value for the data counter by the number of bytes
used for each level.  Operations at any specific ply would then be done by
smaller fixed increments of the data counter in a sequence that would be
the same for all plies.

A board position would be stored as 3 sets of 4 bytes each, one set for
the white pieces (including kings), one set for the Black pieces
(including Kings), and 1 set for all Kings.  White Kings would then be
gotten when needed by ANDing the bytes for the White pieces with the bytes
for the Kings.  The 32 bits in the sets of 4 bytes would refer to the
individual squares on the board and a piece on a given square would be
shown by a 1 in the corresponding bit position.  This method of
representation is actually wastefull of space in that each set of 4 bytes
will usually have fewer than 12 bits on but the packing and unpacking
requirements for any known more-compact representation would be
horrendous.

Two scores, the α value and the β value must be saved with each board.
While it would be possible to limit each score to 4 bits, it seems
advisable to allow 8 bits for each so 2 bytes are so needed at each ply.

Saving moves

All available legal moves from a given board position can be stored in 4
sets of 4 bytes each.  Each set would correspond to a given direction on
the board, one for right forward moves, one for left forward moves, one
for left backward moves, and one for right backward moves, the bit
positions occupied showing the piece position which can make the move.  As
moves are explored, the bits showing these moves are errased and when all
16 bytes are empty the program backs up a level and tries for moves less
far down the move tree.  Several flag bits are required, one bit to tell
if the moves are jump moves or not, one bit to tell which color is moving,
another bit to keep track of the ply level, still another to tell if the
next lower move was a jump, etc.  One might be able to get by with one
byte of such flags but it would be safer and certainly easier if at least
two bytes were used.

The straight forward procedure would be to compute and store all available
moves with each board.  Initially all directions must be investigated to
make sure that there are no jumps, since jumps must be taken.  Thereafter
one could save space by keeping only one byte full of moves, with some
bookkeeping being required, and then by recomputing each additional byte
full as needed.  This would save as many as 14 bytes per ply.

An alternate proceedure would be to keep only the count of the moves that
have been processed from each board position and to recompute all moves
over again each time and then count down to find what the next one would
be but little if any space would be saved by this procedure.
TENTATIVE DATA STORAGE MAP

As a first pass we will assign the following relative locations for tree data

Contents	Location

Active pieces	0 thru 3
Passive pieces	4 thru 7
Kings		8 thru B
Move byte	C
Flag byte	D
Score bytes	E and F

We will store tree data in the RAM such that the starting address is
divisable by 256, that is, so that the second byte of this address is
zero.  The first byte of the data counter will be set at the start of the
tree analysis and will remain unchanged during the analysis.  It may, of
course, be necessary to store the data counter ocassionaly during
excursions to subroutines, but the F8 code allows this to be done fairly
easily.  We will reserve H (scratchpad registers 10 and 11) for storing
the value of the data counter when it is set to point to the start of a 
data block as outlined below.

The tree data will consist of blocks of 16 bytes, one block for the
initial board situation at the start of any one move and the additional
blocks, one for each ply in depth to which the analysis is to be carried.
Normally this depth will be a fairly small number but provision will have
to be made for perhaps 16 blocks.  It does not seem that RAM space will be
at all critical during the tree analysis and most of this space is used
only during the tree analysis itself and so it can be reused by other
parts of the overall program.  A FREE STORAGE scheme will definitely not
have to be used by this part of the program.

Several scratchpad registers will be reserved for pertinent data relative
to the tree   One of these will contain the 
ply that is currently under analysis and this number will
be stored in the left half of the byte so that what is actually stored
will be the second data counter byte for the start of the ply block in
question.  We will assume that this is register 8q

Each time the ply is changed the program will update the first 4 bits of
the second data counter byte and each section of the code that deals with
some particular item of tree data will begin by replacing the last 4 bits
of the second data counter with an appropiate value.  For example, the
SELECT code, which operates on the Move byte only, will set these last 4
bits to C.
*CTAB EMPTY and LEGAL codes

*Counts bits in byte contained in scrarchpad 1 and returns results in scratchpad 2
*Named for an old 7094 command that did just this
CAQ	
	POP

*   Scratchpad
*    Register	Contents

*	0	Current byte of ACTIVE
*	1	Current byte of Passive
*	2	Working space,
*	3
*	4	Count of moves found (on going forward only)
*	5	Counter, defining ACTIVE byte under consideration
*	6	MOVE byte
*	7	FLAG byte
*	8	PLY in the left 4 bits

*This code now occupies about 230 bytes instead of the 200 allowed
*and it will still have to be augmented to handle both Black and White as active.

*EMPTY will probably just preceed FIND
*To generate EMPTY and save it in scratchpad registers O'21', O'22', O'23, O'24'
*Registers O'20' and O'25' are set to zero as guard bytes for off-board references
*Assume that H has been updated, that ACTIVE, PASSIVE and KINGS have been stored,
*On going forward  Scratchpad registers 5, 6, and 7 are all set to zero
*On backing up, 6 and 7 are set from RAM 
EMPTY	LISU	2		This buffer used for EMPTY
	LISL	0
	LR	DC,H		H always contains DC value for start of PLY block
	CLR
	LRI	I,A		A guard byte at start
	BR	EMP3
EMP2	LIS	1
	ADC
EMP3	LR	Q,DC
	LM			Get ACTIVE byte
	LR	0,A		Save it temporarily
	LIS	4		Index to PASSIVE byte
	ADC
	LM			Get PASSIVE byte
	AS	0		Add ACTIVE byte
	COM
	LR	I,A		Save it in scratchpad O'20' and increment ISAR
	LR 	DC,Q		Reload DC for last used ACTIVE
	NI	7
	CI	5
	BNZ	EMP2		Loop
	CLR
	LRI	S,A		A guard byte at the end

*To find all moves on going forward along the tree
*The first found move byte will be left in the MOVE byte and the FLAG byte will
*be set to show whether the move is a jump or not and to tell which of the
*possible move bytes is actually saved in the RAM MOVE byte.
*The count of the total number of moves will be left in scratchpad 4.
*This number (to max of 7) will also be stored in the spare bits of the FLAG byte.
*Entry on going forward at FIND, on backing up at Next

NEXT	LISU	2
	LR	DC,H
	LI	H'C'

FIND	LISU	2		EMPTY bytes are here
	LISL	1		Remember 0 is a guard byte
	LIS	4		Start with Jump moves


	BR	FIN2
FIN1	CLR
	LISL	1		Remember 0 is a guard byte
FIN2	LR	5,A		Used to indicate J or N
	LIS	3
	LR	4,A		Used to count starting byte
FIN3	LIS	3
	LR	3,A		Used to count direction
	LR	DC,H		Start with the first byte of ACTIVE
	AS	4		Add to get current byte
	ADC
	LM			Get ACTIVE byte
	LR	0,A		Save it
	AS	I		Just to increment ISAR for next EMPTY byte
FIN4	LR	A,3		Get direction number
	AS	5		Add in J or N indicator
	DCI	FINT
	ADC
	LM
	DCI	RFJ
	ADC
	LR	Q,DC
	LR	PO,Q
FINT	DC	(RBN-RFJ)
	DC	(LBN-RFJ)
	DC	(LFN-RFJ)
	DC	(RFN-RFJ)
	DC	(RBJ-RFJ)
	DC	(LBJ-RFJ)
	DC	(LFJ-RFJ)
	DC	(RFJ-RFJ)

RFJ	LR	A,I		Increment to next byte
	LR	A,D		Get EMPTY byte and set ISAR back
	SR	1		Shift it right by 1
	NI	H'77'		Save only 6 particular bits
	LR	2,A		Corrected destination byte
	LR	DC,H
	AS	4
	AI	5		INDEX to PASSIVE byte
	ADC
	LM			Get PASSIVE byte
	SL	4
	LR	1,A
	LIS	1
	ADC
	LM
	SR	4
	SR	1
	BR	FINR

LFJ	LR	A.I		Increment to the next byte
	LR	A,D		Get EMPTY byte and set ISAR back
	SL	1		Shift it left by 1
	NI	H'EE'		Save only specific 6 bits
	LR	2,A
	LR	DC,H
	AS	4
	AI	5		INDEX to PASSIVE byte
	ADC
	LM			Get PASSIVE byte
	SL	1		Shift it left by 5 total
	SL	4		Shift it left by 4
	LR	1,A		Save it
	LIS	1		Now the next PASSIVE byte
	ADC
	LM
	SR	4
	BR	FINR

LBJ
	LR	DC,H
	AS	4
	AI	8		INDEX to PASSIVE byte
	ADC
	LM			Get King byte
	NS	A,0		AND it to Active from 0
	BZ	FINR		No backward moves for this byte
	LR	0,A		And save it
	LR	A,D		Decrement to earlier byte
	LR	A,I		Get EMPTY byte AND SHIFT ISAR BACK
	SL	1		Shift it left by 1
	NI	H'EE'		Save only 6 particular bits
	LR	2,A
	LI	H'F8'		Actually -4
	ADC			to index to passive byte
	LM			Get PASSIVE byte
	SR	4
	LR	1,A
	LIS	1		Now the next PASSIVE byte
	ADC
	LM
	SL	4		Shift it left by 5
	SL	1		Shift it left by 5
	BR	FINR

RBJ	LR	DC,H
	AS	4
	AI	8		INDEX to PASSIVE byte
	ADC
	ADC
	LM			Get King byte
	NS	A,0
	BZ	FINR		No backward moves for this byte
	LR	0,A
	LR	A,D		Decrement ISAR
	LR	A,I		Get EMPTY byte and reset ISAR
	SL	1		Shift it left by 1
	NI	H'EE'		Save only specific 6 bits
	LR	2,A
	LI	H'FD'		Actually -3
	ADC
	LM			Get PASSIVE byte
	SL	4		Shift it left by 5
	SL	1		Shift it left by 5
	LR	1,A		Save it
	LIS	1		Now the next PASSIVE byte
	ADC
	LM
	SR	4
	BR	FINR

RFN	LR	A,I		Get empty byte
	SL	4
	LR	1,A
	LR	A,D
	SR	4
	SR	1
	BR 	FINR

LFN	LR	A,I
	SL	4
	SL	1
	LR	1,A
	LR	A,D
	SR	4
	BR	FINR  

LBN	LR	DC,H
	AS	4
	AI	8		INDEX to PASSIVE byte
	ADC
	LM			Get King byte
	NS	A,0		AND it to Active from 0
	BZ	FINR		No backward moves for this byte
	LR	0,A		And save it
	LR	A,D
	SR	4
	LR	1,A
	LR	A,I
	SL	4
	SL	1
	BR	FINR

RBN	LR	DC,H
	AS	4
	AI	8		INDEX to PASSIVE byte
	ADC
	LM			Get King byte
	NS	A,0		AND it to Active from 0
	BZ	FINR		No backward moves for this byte
	LR	0,A		And save it
	LR	A,D
	SR	4
	SR	1
	LR	1,A
	LR	A,I
	SL	4
FINR	AS	1		Add in other PASSIVE pieces
	NS	0		And in the ACTIVE byte
	NS	2		And the modified PASSIVE byte
	BZ	FINL		Branch on zero
	LR	1,A		Save temporarily
	PI	CTAB		To count bits on in 1 and leave results in 2
	LR	A,6		Count of moves found
	AS	2
	LR	6,A
	
	LR	DC,H		Reset to locate MOVE byte
	LIS 	H'C'
	ADC
	LM
	NI	H'FF'		To set status
	BNZ	FINL		A move byte is already stored
	LR	A,1		Get move byte
	ST			and store it
	LIS	1		Now go to flag byte
	ADC
	LR	A,3		Get 2 bits that define direction
	AS	5		Add J or N bit
	SL	1
	SL	1
	AS	4		Add 2 bits defining the ACTIVE byte
	ST			Store the new FLAG byte
FINL	DS	3		Decrement direction
	BP	FIN4		BR if not negative
	DS	4		Decrement byte count
	BP	FIN3
	LR	A,5
	DS	5		Decrement J or N indicator
	BP	FIN1
*Now to add count of moves found to Flag byte
	LR	DC,H
	LIS	H'D'		Get back to the flag bit
	ADC
	LR	A,6
	CI	7
	BN	FIN6
	LIS	7		Limit count to 7
	BR	FIN7
FIN6	LR	A,6
FIN7	SL	5
	LR	6,A		Put limited value back in 6
	AM			Add in old flag byte
	ST			and store
Subroutine to  move 4 bytes from RAM to Scratchpad registers	16 thru 19
RASC	LISL	0
	BR	RASE
*Subroutine to move 4 bytes from RAM to SC 20 thru 23
RAS2	LISL	4
RASE	LISU	2
	LIS	4
	LR	0,A
RASL	LM
	LR	A,I
	DS	0
	BNZ	RASL
	POP

*Subroutine to move 4 bytes from SC24 thru 28 to RAM (Kings)
SCR3	LISL	0
	LISU	3
	BR	SCRF
*Subroutine for moving 4 bytes from Scratchpad registers 16 thru 19 to RAM
SCR1	LISL	0
	BR	SCRE
*Subroutine to move 4 bytes from SC 20 thru 23 to RAM	(former passive)
SCR2	LISL	4
SCRE	LISU	2
SCRF	LIS	4
	LR	0,A
SCRL	LR	A,I
	ST
	DS	0
	BNZ	SCRL
	POP

*To move pieces forward with sides reversed
FORW	LR	DC,H
	LI	H'10'
	ADC
	LR	Q,DC		We will need this later
	LIS	4
	LR	0,A		To use as a counter
	ADC
	XDC
	LR	DC,H
	PI	FOR2		Former ACTIVE to PASSIVE
	XDC
	LR	DC,Q
	XDC
	PI	FOR2		FORMER PASSIVE to ACTIVE
	LR	DC,Q
	LIS	8
	ADC
	XDC
	PI	FOR2		KINGS to KINGS
	XDC
	CLR
	ST			Zero MOVE byte
 	ST			and FLAG
	ST			and SCOREs
	ST			and SCOREs
	POP
* Registers, Subroutines

Tree data will be stored in blocks of 16 bytes, one for each ply depth.  Data
within each block will be located as follows:

Bytes		Contents

0 thru 3	ACTIVE pieces
4 thru 7	PASSIVE pieces
8 thru 11	KINGS
12		MOVE byte
13		FLAG byte (dir in 0,1  byte in 2,3  J in 4  H'FF' going fore)
14		SCORE
15		unassigned

When blocks of data are to be operated on, they are moved from RAM into the
Scratchpad registers 16 thru 31.  Scratchpad registers 32 to 35 are used for 
EMPTY as created by code EMPTY with 36 left empty as a guard.  At the time
that Empty is filled register 31 is also set to zero as a lower guard.

Scratchpad registers 0 thru 8 are normally used as follows:

Register	Usage
0		general purpose
1
2	King move flag
3	Move byte during generation
4	Byte pointer (bits 0 and 1 from FLAG byte)
5	Move direction (bits 2, 3 and 4 from FLAG byte)
6	MOVE bit extracted from MOVE
7	FLAG byte for analysis
8	Color of ACTIVE (0 if Black)

*Subroutine to move 4 bytes from one location in RAM to another
FOR2	LIS	4
	LR	0,A
FORL	LM			Get Byte to move
	XDC
	ST			Store in new location
	XDC
	DS	0
	BNZ	FORL		Loop
	POP

*Subroutine to move 16 bytes from RAM into SC 16 thru 31
RASC	LISU	2
	LISL	0
	LIS	8
	LR	0,A
	PI	RASM
	LISU	3
	LISL	0
	LI	8
	LR	0,A
	PI	RASM
	
RASM	LIS	4
	LR	0,A
RASL	LM
	LR	S,A
	DS	0
	BNZ	RASL
	POP

*Subroutine to move 16 bytes from SC 16 thru 31 to RAM, reversing ACTIVE and PASSIVE
SCRC	LISU	2
	LISL	4
	PI	SCRM
	LISL	0
	PI	SCRM
	LISU	3
	LISL	0
	PI	SCRM
	PI	SCRM
	POP

SCRM	LIS	4
	LR	0,A
SCRL	LR	A,I
	ST
	DS	0
	BNZ	SCRL
	POP

*To compute 4 bytes which show the empty squares on the board.
*These are stored in SC 33 thru 36 with SC 32 and SC 37 set to zero as guards.
*Note especially that the EMPTY locations are displaced
EMPTY	LISU	3
	LISL	0
	CLR
	LR	S,A		Make sure guard byte is empty
	LISU	1		Start with ACTIVE
	LIS	4
	LR	0,A
	BR	EMP3
EMP2	LR	A,SI
	AI	H'2F'		Actually subtracting 17 
	LR	SI,A
EMP3	LR	A,S
	LR	1,A
	LR	A,IS
	AI	4
	LR	SI,A
	LR	A,S
	AS	1
	LR	1,A
	LR	A,SI
	AI	H'D'		Add 13 to get to the correct EMPTY location
	LR	IS,A
	LR	A,1
	COM
	LR	I,A
	DS	0
	BNZ	EMP2
	CLR
	LR	S,A		Upper guard byte
	POP
* FORE AFT FIND

** TEST FOR MAX DEPTH MUST BE PUT IN THE FOLLOWING
FORE	LR	DC,H
	LI	H'10'
	ADC
	LR	H,DC
	PI	RASC		Get correct board into SC
	LI	H'FF'
	LR	6,A		So all moves will be found
	PI	FIND

**Score back-up must be put into the following****
and test made for ply for time to stop
AFT	LR	A,11
	COM
	AI	H'10'
	COM
	LR	DC,H
	PI	RASC
	LISU	2
	LISL	5
	LR	A,I
	LR	6,A		The remaining MOVE byte
	LR	A,S
	NI	H'FF'		To set STATUS
	LR	A,S
	LR	7,A		The FLAG byte
	BNZ	SELE
	NI	H'F'		Remove J bit
	AI	1
	LR	4,A
	NI	H'10'		Is board exhausted
	BZ	AFT		Must back up more
	LR	A,4
	NI	3
	LR	5,A		The direction in 5
	LR	A,4
	SR	1
	SR	1
	LR	4,A		The byte pointer in 4
**MUST USE A JUMP TABLE WITH 5 TO ENTER FIND PROPERLY

FIND	LISU	2
	LISL	0		Start with byte 0
*Look for jump moves first
	LIS	0
	LR	4,A		Used to distinguish byte
JLOP	LR	A,S
	LR	6,A		We will need this several times
	LR	3,A		So save it in 2 places
RFJ	LR	A,IS
	LR	4,A		We'll have to get back here
	LR	A,8		Get color of Active
	NI	H'7'		To set status
	BZ	RFJ2		Black is ACTIVE
	LISU	2		Only kings can move this way
	LR	A.S
	NS	6
	BZ	RBJ		No RF or LF moves for this byte
	LR	3,A		Correct for kings
RFJ2	LR	A,IS
	AI	2	To next forward EMPTY byte (remember displacement)
	LR	IS,A
	LISU	3
	LR	A,S
	SR	1
	NI	H'77'		Save 6 particular bits only
	NS	3
	LR	3,A
	LR	A,IS
	AI	2		(remember displacement)
	LR	IS,A
	LISU	2		This gets us to the right KING byte
	PI	RFJN		This returns the RFJ byte in 3
	BZ	LFJ
	LIS	H'C'		For the MOVE byte location
	LR	IS,A
	LR	A,S		Has one been stored?
	NI	H'FF'		To set STATUS
	BNZ	FIN3
	LR	A,3
	LR	I,A		Store MOVE and index to FLAG
	LR	A,4		For the FLAG byte
	SL	1
	SL	1
	AI	H'11'		RFJ pointer
	LR	S,A
FIN3	LR	A,6		This is H'FF' if going forward and 0 on back-up
	XI	H'FF'
	BZ	FIN4
	BR	SELE		Stop after finding a valid MOVE byte
FIN4	PI	CAQ		To count bits in 3
	

LFJ
	LR	A,4		Get back in step
	LR	IS,A
	LR	A,S
	LR	3,A
*THIS CODE WILL BE QUITE SIMILAR TO RLJ CODE

*Subroutine used both by RFJ and RJN
RFJN	LR	A,S
	SL	4
	LR	0,A
	LR	A,IS
	AI	1
	LR	IS,A
	LR	A,S
	SR	4
	SR	1
	AS	0
	NS	3
	LR	3,A		The RFJ or RJ byte
	POP

LFJN	LR	A,S
	SL	4
	SL	1
	LR	0,A
	LR	A,IS
	AI	1
	LR	IS,A
	LR	A,S
	SR	4
	AS	0
	POP
*SELECT is entered with H set for the correct ply position in RAM

*SELECT	extracts one bit (the rightmost one) from the MOVE byte storing it in
Scratchpad 6 and it puts the FLAG byte in SC 7 with the last 2 bits into SC 5.
SELECT	LR	DC,H		Load DC  with starting location for current ply
	LI	H'C'		The relative location of the MOVE byte
	ADC			Add it to the DC
	LR	Q,DC		Save it as DC will be incremented willy-nilly
	LM			Get the byte to be operated on
	LR	0,A		Save it temporarily
	NI	H'FF'		TO set status byte
	BZ	GETB		Branch on zero to code to get next MOVE byte
	COM			Complement the ACC
	AI	1		Really subtracting 1
	NS	0		Extract right-most on-bit only
	LR	6,A		Save it in 6
	XS	0		This gets the remaining bits
	LR	DC,Q		(DC was incremented, remember)
	SM			So put them back
	LM			Get FLAG byte while we are at it
	LR	7,A		Save it in 7
	NI	3		Separate the byte indicator part
	LR	5,A		Save it in 5
	LR	A,7
	SR	1
	SR	1		Separate out the direction bits
	LR	4,A		Save them in 4

*Now process ACTIVE and KINGS for source deletion
DELE	LR	DC,H
	LISU	2
	LISL	0
	LR	A,IS
	AS	5
	LR	IS,A		Locate ACTIVE byte with piece moving
	LR	A,S
	XS	6		Delete moving piece
	LR	S,A		from byte
	LISU	3		To get to corresponding KING byte
	LR	A,S
	NS	6		Was the piece a king?
	BZ	DEL2
	XS	S		If it was delete king bit
	LR	S,A
	LI	7		Non-zero in 2 for king 
DEL2	LR	2,A		Save as a flag for kind of piece moving

*Now locate captured piece if jump or find destination in normal move
	LR	6		Recall MOVE byte
	SR	4
	BZ	INRH		Bit was in right half of byte
INLH	LR	3,A		Save partially shifted MOVE bit
	LR	A,4		Get direction
	NI	1		To test right-most bit
	BZ	INL2		RF or LB move where 4 shift is correct
	LR	A,3
	SR	1		LF and LB require an additional shift
	LR	3,A
INL2	LR	A,4		Now test for fore or aft
	NI	2
	BZ	BOTH		Bit was off so forward move and no byte shift needed
	LR	A,D		Only to decrement ISAR
INL3	BR	BOTH

INRH	LR	6		Get MOVE byte back
	SL	4		Left shift if in right half
	LR	3,A		Save partially shifted MOVE bit
	LR	A,4		Get direction
	NI	1
	BNZ	INR2		LF or RB wwhere 4 shift is correct
	LR	A,3
	SL	1		RF and RB require an additional shift
	LR	3,A
INR2	LR	A,4		Now test fore and aft
	NI	2
	BNZ	BOTH
	LR	A,I		Only to increment ISAR
BOTH	LR	A,4		Now is this a jump or a normal move?
	NI	4
	BZ	NORM		Normal move case
	LR	A,S		Get King Byte corresponding to captured piece
	NS	3		Was piece a king?
	BZ	BOT2		No
	XS	3		Delete it
	LR	S,A		And replace byte
BOT2	LISU	2		Get back to right buffer for ACTIVE and PASSIVE
	LR	A,IS
	AI	4		Increment to PASSIVE byte
	LR	IS,A
	LR	A,S		Get appropiate PASSIVE byte
	XS	3		Delete capture
	LR	S,A		And return byte

	LISU	2		Back to moved from location
	LISL	0
	LR	A,IS
	AS	5
	LR	IS,A
	LR	A,4		Get direction
	NI	1		Test for right or left
	BZ	BOT3
	LR	A,6
	SR	1
	BZ	BOT4
BOT3	LR	A,6
	SL	1
BOT4	LR	3,A		Save displaced bit in 3
	LR	A,4
	NI	2		Test for fore or aft
	BZ	BOT5
	LR	A,D		Decrement ISAR
	BZ	BOT6
BOT5	LR	A,I		Increment ISAR
BOT6	LR	A,S		Now get right byte
	AS	3		Insert piece
	LR	S,A
	LR	A,2		Get king indicator
	NI	7
	BZ	BOT7		Not a king
	LR	A,IS
	AI	4		Go to correct king byte
	LR	A,S
	AS	3
	LR	S,A
*Now restore pieces to RAM, switching ACTIVE and PASSIVE
BOT7	PI	SCRA


*Now make a normal move, (remember we were indexed to the king buffer)
NORM	LR	A,2		This was set to non-zero if King moving
	NI	7
	BZ	NOR2		Not a king
	LR	A,S		Get corresponding king byte for destination
	AS	3		Insert moved king
	LR	S,A		And replace byte
NOR2	LISU	2		Get back to Active pieces
	LR	A,S
	AS	3
	LR	S,A		Put in moved piece
*Normal move completed
UPDATE

Having selected a piece to be moved the program notes the appropiate byte
and direction from the FLAG word and then proceeds to generate the
resulting board.  The final destination of the moving piece relative to its
initial location can be easily determined by a table look-up operation
but this may take more space than is justified.  On the other hand there are
numerous factors that must be considered if this is to be computed and it is
not at all certain as to which procedure will take less space.  Both methods
will probably have to be coded before a decision can be reached.

Evaluation

The amount of code space required for the evaluation is perhaps subject to
the greatest compression or expansion of any part of the program.  The
writing of this part of the code can well be left until after some of the
other parts have been stabilized.
α-β Scoring

The Alpha Beta algorithm is the most important algorithm that is involved in
a tree search.  It is also the hardest to explain although every one who plays
games such as checkers knows it instinctively and makes full use of it in
his own play.  This is not the place to elaborate on this subject but a great
deal of care must be given to the proper programming of this part of the code.
My present guess that it can be done in 50 bytes but I could be grossly in
error on this.  The methods that I have used for this previously have been
rather wasteful of code space.
Opponents move checking

This can most easily be done by using the LEGAL move generator to find out
all of the available moves and then to simply see if the opponents move is in
this list.  30 extra instructions should suffice for this.

The problem of providing the mechanism for the opponent to enter his move is
perhaps harder to solve and I will need some help on this.
DISPLAY

I am not at present well enough informed about the display features associated
with the equipment to comment on this.  I have assumed that at least 200 bytes
would have to be allowed for this function.